// File:    expr.h
// Author:  Brian Vanderburg II
// Purpose: Expression object
//------------------------------------------------------------------------------


#ifndef __EXPREVAL_EXPR_H
#define __EXPREVAL_EXPR_H

// Includes
#include <string>
#include "error.h"

// Part of expreval namespace
namespace ExprEval
{
// Forward declarations
class ValueList;
class FunctionList;
class Node;

// Expression class
//--------------------------------------------------------------------------
class Expression
{

public:

    Expression();
    virtual ~Expression();

public:

    // Variable list
    void
    SetValueList (
        ValueList *vlist);

    ValueList*
    GetValueList() const;

    // Function list
    void
    SetFunctionList (
        FunctionList* flist);

    FunctionList*
    GetFunctionList() const;

    // Parse an expression
    bool
    Parse (
        const std::string& exstr,
        const bool stop_when_numeric_limits_reached);

    // Clear an expression
    void
    Clear();

    // Evaluate expression
    double
    Evaluate();

    // Evaluate expression and it's first order derivative value
    std::pair<double, double>
    Evaluate (
        const std::string& var_symbol);

    // Evaluate expression and it's second order derivative value
    std::pair<double, double>
    Evaluate (
        const std::string& var_symbol_1,
        const std::string& var_symbol_2);

    const std::string&
    getExprString() const;

    /*
     * for example, if var_map_name is vars,
     * then "a+exp(b)"
     * will be renamed as "vars[a] + exp(vars[b])"
     */
    std::string
    get_renamed_expression (
        const std::string& var_map_name) const;

protected:

    ValueList *m_vlist;
    FunctionList *m_flist;
    Node *m_expr;

    /*
     * the expression that to be parsed.
     * this is mainly used for output information
     */
    std::string m_expr_str;

    ErrorInfo m_errors;

private:

    Expression (const Expression&);
    Expression& operator = (const Expression&);
};

} // namespace ExprEval

#endif // __EXPREVAL_EXPR_H
